/*
 * QE3e Qt Quick 3D Engine.
 * Copyright (C) 2010 Joris Vaillant and Mathieu Pujol 
 * <joris.vaillant@gmail.com>  <mathieu.pujol87@gmail.com>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "Loader.h"

//Qt
#include <QDebug>

//std
#include <math.h>

namespace qe3e
{

  Loader::Loader():QThread()
  {
    reset();
    mCenter=false;
    mNormalize=false;
    mGenerateNormal=false;
  }

  void Loader::startLoading(const QString & fileName, bool detachThread, Priority priority)
  {
    if(!isRunning())
    {
      reset();
      mFileName = fileName;

      mLog<<"Start loading "+mFileName+" in thread "+QString::number((int)QThread::currentThreadId());

      emit progress(0);
      emit currentTask("Start Loading");
      if(detachThread)
      {
        start(priority);
      }
      else
      {
        run();
      }
    }
  }

  void Loader::getResult(Item * & rootItem, QList<Item *> & itemCreated)
  {
    if(!isRunning())
    {
      rootItem = mRoot;
      itemCreated = mItemList;
      reset();
    }
    else
    {
      rootItem=NULL;
    }
  }

  const QStringList & Loader::getLog() const
  {
    return mLog;
  }

  QString Loader::printLog() const
  {
    QString str;
    foreach(QString str2, mLog)
    {
      str += str2 +'\n';
    }
    return str;
  }

  void Loader::reset()
  {
    mFileName="";
    mRoot=NULL;
    mItemList.clear();
    mLog.clear();
  }

  void Loader::run()
  {
    bool succeed = loadingAlgorithme();
    if(!succeed)
    {
      reset();
    }
    emit progress(100);
    emit currentTask("End of Loading");
    emit endOfLoading(succeed);

  }

  void Loader::setNormalizeVertex(bool enable)
  {
    mNormalize=enable;
  }

  void Loader::setCenterMesh(bool enable)
  {
    mCenter=enable;
  }

  void Loader::setGenerateNormal(bool enable)
  {
    mGenerateNormal=enable;
  }

  Loader::FunctorNormalizeAndCenter::FunctorNormalizeAndCenter(bool center, bool normalize)
  {
    mGravityCenter=QVector3D(0,0,0);
    mData=NULL;
    mCenter=center;
    mNormalize=normalize;
  }

  void Loader::FunctorNormalizeAndCenter::operator()(QPair<int,int> index)
  {

    for(int i=(index.first*3) ; i<(index.second*3) ; i+=3)
    {
      if(mNormalize)
      {
        mData[i]=mGravityCenter.x() + ( mData[i] - mGravityCenter.x())*mScaleFactor;
        mData[i+1]=mGravityCenter.y() + ( mData[i+1] - mGravityCenter.y())*mScaleFactor;
        mData[i+2]=mGravityCenter.z() + ( mData[i+2] - mGravityCenter.z())*mScaleFactor;
      }

      if(mCenter)
      {
        mData[i]=  mData[i]-mGravityCenter.x();
        mData[i+1]=  mData[i+1]-mGravityCenter.y();
        mData[i+2]=  mData[i+2]-mGravityCenter.z();
      }
    }
  }

  Loader::FunctorNormalizeNormal::FunctorNormalizeNormal()
  {
    mData=NULL;
  }

  void Loader::FunctorNormalizeNormal::operator ()(QPair<int,int> index)
  {
    for(int i=(index.first*3) ; i<(index.second*3) ; i+=3)
    {
      float length = sqrt(mData[i]*mData[i] + mData[i+1]*mData[i+1] + mData[i+2]*mData[i+2]) ;
      mData[i]/=length;
      mData[i+1]/=length;
      mData[i+2]/=length;
    }
  }
}

